import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { resetRouter, asyncRoutes,constantRoutes } from "@/router";
import router from '@/router';
import cloneDeep from 'lodash/cloneDeep'


const getDefaultState = () => {
  return {
    token: getToken(),
    name: "",
    avatar: "", //用户头像
    menus:[],  //菜单信息
    roles:[],  //角色信息
    buttons:[], //可用按钮
    latestRoutes:[], //最终使用的路由菜单
    resultAsyncRoutes:[],  //对比之后的路由菜单
  };
};

const state = getDefaultState();

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState());
  },
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  SET_USERINFO:(state,userInfo) =>{
    state.name=userInfo.name;
    state.avatar = userInfo.avatar;    //用户头像
    //菜单权限标记
    state.menus = userInfo.routes;
    //按钮权限标记
    state.buttons = userInfo.buttons;
    //角色
    state.roles = userInfo.roles;
  },

  //最终计算出的异步路由
  SET_RESULTASYNCROUTES:(state,asyncRoutes)=>{
    //vuex保存当前用户的异步路由，注意，一个用户需要展示完成路由：常量、异步、任意路由
    state.resultAsyncRoutes = asyncRoutes;
    //计算出当前用户需要展示所有路由
    state.latestRoutes = constantRoutes.concat(state.resultAsyncRoutes);
    //给路由器添加新的路由
     router.addRoutes(state.latestRoutes)
 }
};

//定义一个函数：两个数组进行对比，对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (asyncRoutes,routes)=>{
  //过滤出当前用户【超级管理|普通员工】需要展示的异步路由
 return asyncRoutes.filter(item=>{
      //数组当中没有这个元素返回索引值-1，如果有这个元素返回的索引值一定不是-1 
     if(routes.indexOf(item.name)!=-1){
       //递归:别忘记还有2、3、4、5、6级路由
       if(item.children&&item.children.length){
           item.children = computedAsyncRoutes(item.children,routes);
       }
       return true;
     }
  })
}


const actions = {
  // user login
  async login({ commit }, userInfo) {
    let result = await login(userInfo);
    if (result.code == 20000 || result.code == 200) {
      commit("SET_TOKEN", result.data.token);
      setToken(result.data.token);
      return "ok";
    } else {
      return Promise.reject(new Error("faile"));
    }
  },

  // get user info
  async getInfo({ commit, state }) {
    let result = await getInfo(state.token);
    if (result.code == 20000 || result.code == 200) {     
      commit('SET_USERINFO',result.data);
      commit('SET_RESULTASYNCROUTES',computedAsyncRoutes(cloneDeep(asyncRoutes),result.data.routes));
    } else {
      return Promise.reject(new Error("faile"));
    }
  },

  // user logout
  async logout({ commit, state }) {
    let result = await logout(state.token);
    if (result.code == 20000 || result.code == 200) {
      removeToken(); // must remove  token  first
      resetRouter();
      commit("RESET_STATE");
    } else {
      return Promise.reject(new Error("faile"));
    }
  },

  // remove token
  async resetToken({ commit }) {
    return new Promise((resolve) => {
      removeToken(); // must remove  token  first
      commit("RESET_STATE");
      resolve();
    });
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
